package com.gitee.cashzhang27.test.boot.other.util;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.resource.ClassPathResource;
import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.events.Event;
import com.itextpdf.kernel.events.IEventHandler;
import com.itextpdf.kernel.events.PdfDocumentEvent;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.property.TextAlignment;
import com.itextpdf.layout.property.VerticalAlignment;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * @author Cash Zhang
 * @version v1.0
 * @since 2019/11/05 20:48
 */
public class PDFUtil {

  /**
   * 读取文件 添加水印
   *
   * @param outName 生成的新的文件 例如：src/main/resources/static/test1.pdf
   * @param readName 读取的文件 例如：src/main/resources/static/test.pdf
   */
  public static void readPdf(String outName, String readName) throws Exception {
    FileOutputStream outputStream = new FileOutputStream(new File(outName));
    PdfWriter pdfWriter = new PdfWriter(outputStream);
    PdfDocument outDocument = new PdfDocument(pdfWriter);
    PdfReader pdfReader = new PdfReader(readName);
    PdfDocument redDocument = new PdfDocument(pdfReader);
    // 添加事件，该事件拥有添加水印
    WaterMark waterMark = new WaterMark();
    outDocument.addEventHandler(PdfDocumentEvent.INSERT_PAGE, waterMark);
    // 获取总页数
    int numberOfPages = redDocument.getNumberOfPages();
    for (int i = 1; i <= numberOfPages; i++) {
      PdfPage page = redDocument.getPage(i);
      // 复制每页内容添加到新的文件中
      outDocument.addPage(page.copyTo(outDocument));
    }
    outDocument.close();
    redDocument.close();
    pdfReader.close();
  }

  /** 读取文件 添加水印 */
  public static void writeWaterMark(byte[] bytes) throws Exception {
    // 内存流
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    PdfWriter pdfWriter = new PdfWriter(outputStream);
    PdfDocument outDocument = new PdfDocument(pdfWriter);
    PdfReader pdfReader = new PdfReader(new ByteArrayInputStream(bytes));
    PdfDocument redDocument = new PdfDocument(pdfReader);
    // 添加事件，该事件拥有添加水印
    outDocument.addEventHandler(
        PdfDocumentEvent.INSERT_PAGE,
        (event -> {
          PdfDocumentEvent documentEvent = (PdfDocumentEvent) event;
          PdfDocument document = documentEvent.getDocument();
          PdfPage page = documentEvent.getPage();
          PdfFont pdfFont = null;
          ClassPathResource resource = new ClassPathResource("font/Simsun.ttc");
          byte[] fontBytes = IoUtil.readBytes(resource.getStream());
          // 将字体包拖到路径下
          try {
            pdfFont =
                PdfFontFactory.createTtcFont(fontBytes, 1, PdfEncodings.IDENTITY_H, false, true);
          } catch (IOException e) {
            e.printStackTrace();
          }
          PdfCanvas canvas =
              new PdfCanvas(page.newContentStreamBefore(), page.getResources(), document);

          new Canvas(canvas, document, page.getPageSize())
              .setFontColor(ColorConstants.LIGHT_GRAY, 0.3F) // 颜色
              .setFontSize(60) // 字体大小
              .setFont(pdfFont) // 字体的格式   即导入的字体包
              // 水印的内容（中英文都支持）    坐标（例如：298f, 421f）  当前页数     最后的值为倾斜度（170）
              .showTextAligned(
                  new Paragraph("阳光租呗电子合约"),
                  298f,
                  421f,
                  document.getPageNumber(page),
                  TextAlignment.CENTER,
                  VerticalAlignment.MIDDLE,
                  0.52F);
        }));
    // 获取总页数
    int numberOfPages = redDocument.getNumberOfPages();
    for (int i = 1; i <= numberOfPages; i++) {
      PdfPage page = redDocument.getPage(i);
      // 复制每页内容添加到新的文件中
      outDocument.addPage(page.copyTo(outDocument));
    }
    outDocument.close();
    redDocument.close();
    pdfReader.close();

    String encode = Base64.encode(outputStream.toByteArray());
    System.out.println(encode);
    String dest = "C:\\Users\\CashZhang\\Desktop\\temp\\test111111.pdf";
    OutputStream out = new FileOutputStream(dest);
    outputStream.writeTo(out);
    out.flush();
    out.close();
  }

  /**
   * 监听事件 添加水印
   *
   * @author Administrator
   */
  protected static class WaterMark implements IEventHandler {

    @Override
    public void handleEvent(Event event) {
      PdfDocumentEvent documentEvent = (PdfDocumentEvent) event;
      PdfDocument document = documentEvent.getDocument();
      PdfPage page = documentEvent.getPage();
      PdfFont pdfFont = null;
      ClassPathResource resource = new ClassPathResource("font/Simsun.ttc");

      InputStream inputStream = resource.getStream();
      byte[] bytes = IoUtil.readBytes(inputStream);

      // 将字体包拖到路径下
      try {
        pdfFont = PdfFontFactory.createTtcFont(bytes, 1, PdfEncodings.IDENTITY_H, false, true);
      } catch (IOException e) {
        e.printStackTrace();
      }
      PdfCanvas canvas =
          new PdfCanvas(page.newContentStreamBefore(), page.getResources(), document);

      new Canvas(canvas, document, page.getPageSize())
          .setFontColor(ColorConstants.LIGHT_GRAY) // 颜色
          .setFontSize(60) // 字体大小
          .setFont(pdfFont) // 字体的格式   即导入的字体包
          // 水印的内容（中英文都支持）    坐标（例如：298f, 421f）  当前页数     最后的值为倾斜度（170）
          .showTextAligned(
              new Paragraph("阳光租呗电子合约"),
              298f,
              421f,
              document.getPageNumber(page),
              TextAlignment.CENTER,
              VerticalAlignment.MIDDLE,
              150);
    }
  }
}
